<template>
    <div class="websocket-monitor">
      <h2>双重心跳监控</h2>
      
      <div class="status-card">
        <h3>连接状态</h3>
        <p>WebSocket状态: 
          <span :class="wsStatusClass">{{ websocketStatus }}</span>
        </p>
        <p>STOMP状态: 
          <span :class="stompStatusClass">{{ stompStatus }}</span>
        </p>
      </div>
      
      <div class="heartbeat-card">
        <h3>心跳信息</h3>
        <p>最后WebSocket原生心跳: {{ lastWsHeartbeat || '无' }}</p>
        <p>最后STOMP协议心跳: {{ lastStompHeartbeat || '无' }}</p>
        <p>心跳统计: {{ heartbeatCount }} 次 (WS: {{ wsHeartbeatCount }}, STOMP: {{ stompHeartbeatCount }})</p>
      </div>
      
      <div class="control-panel">
        <button @click="connect" :disabled="connected">连接</button>
        <button @click="disconnect" :disabled="!connected">断开</button>
      </div>
    </div>
  </template>
  
  <script>
  import { Client } from '@stomp/stompjs';
  import SockJS from 'sockjs-client';
  
  export default {
    name: 'DualHeartbeatMonitor',
    data() {
      return {
        connected: false,
        stompClient: null,
        sockJSClient: null,
        
        // 状态信息
        websocketStatus: '未连接',
        stompStatus: '未连接',
        
        // 心跳信息
        lastWsHeartbeat: null,
        lastStompHeartbeat: null,
        heartbeatCount: 0,
        wsHeartbeatCount: 0,
        stompHeartbeatCount: 0,
        
        // 监控定时器
        monitorInterval: null,
        lastActivityTime: null
      };
    },
    computed: {
      wsStatusClass() {
        return {
          'status-text': true,
          'connected': this.websocketStatus.includes('已连接'),
          'disconnected': !this.websocketStatus.includes('已连接')
        };
      },
      stompStatusClass() {
        return {
          'status-text': true,
          'connected': this.stompStatus.includes('已连接'),
          'disconnected': !this.stompStatus.includes('已连接')
        };
      }
    },
    methods: {
      connect() {
        // 创建SockJS连接
        this.sockJSClient = new SockJS('http://localhost:8080/ws-endpoint');
        
        // 监听原生WebSocket事件
        this.setupNativeWebSocketListeners();
        
        // 创建STOMP客户端
        this.stompClient = new Client({
          webSocketFactory: () => this.sockJSClient,
          
          // 连接成功回调
          onConnect: () => {
            this.connected = true;
            this.stompStatus = 'STOMP已连接';
            this.lastActivityTime = new Date();
            
            // 开始监控连接状态
            this.startMonitoring();
            
            console.log('STOMP连接已建立');
          },
          
          // 断开连接回调
          onDisconnect: () => {
            this.connected = false;
            this.stompStatus = 'STOMP已断开';
            this.websocketStatus = 'WebSocket已断开';
            this.stopMonitoring();
            
            console.log('STOMP连接已断开');
          },
          
          // STOMP心跳配置
          heartbeatIncoming: 10000,  // 期望从服务器接收心跳的间隔(ms)
          heartbeatOutgoing: 10000,  // 向服务器发送心跳的间隔(ms)
          
          // STOMP调试信息（用于捕获STOMP心跳）
          debug: (str) => {
            if (str.includes('<<< PONG') || str.includes('>>> PING')) {
              this.lastStompHeartbeat = new Date().toLocaleTimeString();
              this.stompHeartbeatCount++;
              this.heartbeatCount++;
              console.log('STOMP心跳:', str);
            }
          },
          
          // STOMP错误处理
          onStompError: (frame) => {
            console.error('STOMP协议错误:', frame);
            this.stompStatus = 'STOMP错误: ' + frame.headers.message;
          }
        });
        
        // 激活STOMP连接
        this.stompClient.activate();
      },
      
      disconnect() {
        if (this.stompClient) {
          this.stompClient.deactivate();
        }
      },
      
      setupNativeWebSocketListeners() {
        // SockJS在建立连接后会提供WebSocket实例
        this.sockJSClient.onopen = () => {
          this.websocketStatus = 'WebSocket已连接';
          
          // 获取底层WebSocket实例
          const ws = this.sockJSClient._transport.url 
            ? this.sockJSClient._transport.ws 
            : null;
          
          if (ws) {
            // 监听原生WebSocket消息
            ws.onmessage = (event) => {
              // 空消息通常是心跳
              if (event.data === '') {
                this.lastWsHeartbeat = new Date().toLocaleTimeString();
                this.wsHeartbeatCount++;
                this.heartbeatCount++;
                console.log('收到WebSocket原生心跳');
              }
            };
            
            // 监听WebSocket关闭
            ws.onclose = () => {
              this.websocketStatus = 'WebSocket已关闭';
            };
            
            // 监听WebSocket错误
            ws.onerror = (error) => {
              this.websocketStatus = 'WebSocket错误: ' + error.message;
            };
          } else {
            console.warn('无法获取底层WebSocket实例，可能使用的是HTTP流传输');
          }
        };
        
        this.sockJSClient.onclose = () => {
          this.websocketStatus = 'WebSocket已关闭';
        };
      },
      
      startMonitoring() {
        this.stopMonitoring();
        
        // 每3秒检查一次连接状态
        this.monitorInterval = setInterval(() => {
          this.checkConnectionStatus();
        }, 3000);
      },
      
      stopMonitoring() {
        if (this.monitorInterval) {
          clearInterval(this.monitorInterval);
          this.monitorInterval = null;
        }
      },
      
      checkConnectionStatus() {
        const now = new Date();
        
        // 检查STOMP连接状态
        if (this.stompClient && this.stompClient.connected) {
          this.stompStatus = 'STOMP已连接 (' + now.toLocaleTimeString() + ')';
        } else {
          this.stompStatus = 'STOMP未连接';
        }
        
        // 检查WebSocket连接状态
        if (this.sockJSClient && this.sockJSClient.readyState === SockJS.OPEN) {
          this.websocketStatus = 'WebSocket已连接 (' + now.toLocaleTimeString() + ')';
        } else {
          this.websocketStatus = 'WebSocket未连接';
        }
      }
    },
    beforeUnmount() {
      this.disconnect();
      this.stopMonitoring();
    }
  };
  </script>
  
  <style scoped>
  .websocket-monitor {
    max-width: 600px;
    margin: 0 auto;
    padding: 20px;
    font-family: Arial, sans-serif;
  }
  
  .status-card, .heartbeat-card {
    background-color: #f5f5f5;
    border-radius: 8px;
    padding: 15px;
    margin-bottom: 20px;
  }
  
  .status-card h3, .heartbeat-card h3 {
    margin-top: 0;
    color: #333;
  }
  
  .status-text {
    font-weight: bold;
  }
  
  .status-text.connected {
    color: #4caf50;
  }
  
  .status-text.disconnected {
    color: #f44336;
  }
  
  .control-panel {
    display: flex;
    gap: 10px;
  }
  
  .control-panel button {
    padding: 8px 16px;
    background-color: #2196f3;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
  }
  
  .control-panel button:disabled {
    background-color: #9e9e9e;
    cursor: not-allowed;
  }
  </style>